#   sniffUpdateFile.RCS.sh
#
#	SNiFF+ V3.0
#
#	Copyright (C) 1994-1998 TakeFive Software GmbH
#	Salzburg, Austria (e-mail: sniff@TakeFive.co.at)
#
#	Author: Sandor Korosi
#
#	Shell script for RCS Interface.
#	Update private file in the private working environment: 
#		- touch private file if it is writable and project is shared
#		- or remove private file if shared file is up-to-date
#		- or check out file into private working environment if private 
#		  file is not up-to-date
#
#       Usage: 
#       sniffUpdateFile.RCS.sh  WorkingDir  FileTypeDir File  RepositoryDir
#                               [-r Revision]  SWS [OWS [System [Delimiter [Null-device]]]]
#
#       WorkingDir    - working directory of the file (with file-type directory)
#       File          - file name
#       RepositoryDir - repository directory of the project (inclusive file type dir and tool dir)
#       System        - <Unix|Windows> 
#
#       17.2.95 Max Weninger
#               set variable 'ARCHIVE' without 'TYPE_DIR' if 'TYPE_DIR' is empty

if [ "$4" = "" ]
then
	echo "Usage: $0  WorkingDir  FileTypeDir  File  RepositoryDir  [-r Revision]  SWS [OWS [System [Delimiter [Null-device]]]]"
	exit 1
fi

TYPE_DIR=$2
FILE=$3
WORKFILE=$1/$FILE
DEBUG=0
SYSTEM=Unix
D=";"
NULL_DEVICE=/dev/null

ARCHIVE=$4/$FILE,v
 
if [ "$5" = "-r" ]
then
	REVISION=$6
	shift 2
else
	REVISION=
fi
 
SWS=$5
 
if [ "$7" != "" ]
then
	SYSTEM=$7
fi
if [ "$8" != "" ]
then
	D=$8
fi
if [ "$D" != " " ]
then
	SWS=`echo "$SWS" | sed -e "s/$D/ /g"`
fi
if [ "$9" != "" ]
then
	NULL_DEVICE=$9
fi
if [ "$SYSTEM" = "Windows" ]
then
	IS_WINDOWS=1
	if [ "$D" != " " ]
	then
		# note: echo "$SNIFF_DIR" won't work since the \ already get expanded
		SNIFF_DIR="`env | grep '^SNIFF_DIR=' | sed -e 's,\\\\,/,g' -e 's,^[^=]*=,,'`" export SNIFF_DIR
	fi
	SWS=`sh -c "echo \"$SWS\""` # ensure full expansion (variable $SNIFF_DIR)
else
	IS_WINDOWS=0
fi
 

# VCS-specific command for check out file without lock
CHECK_OUT="co -V5 -q -r$REVISION -f \"$ARCHIVE\" $WORKFILE"
# VCS-specific command for check whether the files are out-of-date
DIFF="rcsdiff -V5 -kkv -q -r$REVISION \"$ARCHIVE\""

# exit if private file has no repository file
if [ ! -r $ARCHIVE ] 
then
	echo "File @B$FILE@B has no repository file ($ARCHIVE)"
	exit 0
fi

# if private file is writable
if [ -w $WORKFILE ] 
then
	# if project is shared
	if [ "$SWS" != "" ]
	then
		# if private file is a symbolic link
		if [ -h $WORKFILE ]
		then
			exit 0
		fi
		echo "Touching private writable file @B$FILE@B"
		if [ "$DEBUG" = "1" ]
		then
			echo touch $WORKFILE
		fi
		touch $WORKFILE
	fi
	exit 0
fi

# if private file is writable for other user and it isn't a symbolic link
if [ "$IS_WINDOWS" = "0" ] 
then
	if [ -f $WORKFILE -a ! -h $WORKFILE ]
	then
		if [ "`ls -l $WORKFILE | awk '{print $1}' | grep w`" != "" ] 
		then
			echo "Warning: Private file @B$FILE@B is writable for other user"
			exit 0
		fi
	fi
fi

# if project is not shared
if [ "$SWS" = "" ]
then
	# if private file is not up-to-date
	if [ "$DEBUG" = "1" ]
	then
		echo $DIFF $WORKFILE
	fi
	eval $DIFF $WORKFILE  > $NULL_DEVICE
	ret=$?
	if [ $ret = 1 ]
	then
		echo "-> Checking @B$FILE@B out"
		# check out local
		if [ "$DEBUG" = "1" ]
		then
			echo $CHECK_OUT
		fi
		eval $CHECK_OUT
	else
		if [ $ret = 2 ]
		then
			exit 1
		fi
	fi
	exit 0
fi

# project is shared
SHARED_FILE=
# if private file does not exist
if [ ! -r $WORKFILE ]
then
	# file is shared
	# search shared file in SWS
	for DIR in $SWS
	do
		SHARED_FILE=$DIR/$TYPE_DIR/$FILE
		if [ -r $SHARED_FILE ]
		then
			break
		else
			SHARED_FILE=
		fi
	done
	# if shared file is not found
	if [ "$SHARED_FILE" = "" ] 
	then
		# check out local
		echo "-> Checking @B$FILE@B out"
		if [ "$DEBUG" = "1" ]
		then
			echo $CHECK_OUT
		fi
		eval $CHECK_OUT
	else
		if [ "$DEBUG" = "1" ]
		then
			echo $DIFF $SHARED_FILE
		fi
		eval $DIFF $SHARED_FILE  > $NULL_DEVICE
		ret=$?
		#  if shared file is not up-to-date
		if [ $ret = 1 ]
		then
			# check out local
			echo "-> Checking @B$FILE@B out"
			if [ "$DEBUG" = "1" ]
			then
				echo $CHECK_OUT
			fi
			eval $CHECK_OUT
		else
			if [ $ret = 2 ]
			then
				exit 1
			fi
		fi
	fi
	exit 0
fi

# file is in local WS
# search shared file in SWS
for DIR in $SWS
do 
	SHARED_FILE=$DIR/$TYPE_DIR/$FILE
	if [ -r $SHARED_FILE ]
	then
		if [ "$IS_WINDOWS" = "1" ]
		then
			break
		fi
		if [ ! -h $SHARED_FILE ]
		then 
			break
		else
			SHARED_FILE=
		fi
	else
		SHARED_FILE=
	fi
done

# if shared file is not found 
if [ "$SHARED_FILE" = "" ] 
then
	# if private file is not up-to-date
	if [ "$DEBUG" = "1" ]
	then
		echo $DIFF $WORKFILE
	fi
	eval $DIFF $WORKFILE  > $NULL_DEVICE
	ret=$?
	if [ $ret = 1 ]
	then
		# check out local
		echo "-> Checking @B$FILE@B out"
		if [ "$DEBUG" = "1" ]
		then
			echo $CHECK_OUT
		fi
		eval $CHECK_OUT
	else
		if [ $ret = 2 ]
		then
			exit 1
		fi
	fi
	exit 0
fi

if [ "$DEBUG" = "1" ]
then
	echo $DIFF $SHARED_FILE
fi
eval $DIFF $SHARED_FILE  > $NULL_DEVICE
ret=$?
 
# if shared file is not up-to-date
if [ $ret = 1 ]
then
	if [ "$DEBUG" = "1" ]
	then
		echo $DIFF $WORKFILE
	fi
	eval $DIFF $WORKFILE  > $NULL_DEVICE
	ret=$?
 
	# if private file is not up-to-date
	if [ $ret = 1 ]
	then
		# check out local
		echo "-> Checking @B$FILE@B out"
		if [ "$DEBUG" = "1" ]
		then
			echo $CHECK_OUT
		fi
		eval $CHECK_OUT
	else
		# if private file is a symbolic link
		if [ -h $WORKFILE ]
		then
			exit 0
		fi
		# private file is up-to-date but shared not
		echo "Touching private read-only file @B$FILE@B"
		if [ "$DEBUG" = "1" ]
		then
			echo touch $WORKFILE
		fi
		touch $WORKFILE
	fi
	exit 0
else
	if [ $ret = 2 ]
	then
		exit 1
	fi
fi

# shared file is up-to-date
if [ -h $WORKFILE ]
then
	exit 0
fi

# remove local
if [ "$DEBUG" = "1" ]
then
	echo rm -f $WORKFILE
fi
rm -f $WORKFILE
if [ $? = 0 ]
then
	echo "Private file @B$FILE@B is deleted, shared file is used"
	exit 0
fi

# file cannot be deleted
echo "Private file @B$FILE@B cannot be deleted"
exit 1
